home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Softshoe / Lisa's Mac Parts / Heap / Heap.cp next >
Text File  |  2000-06-23  |  5KB  |  268 lines

  1. // Heap.cp
  2. #define Heap_cp
  3.  
  4. #ifndef Heap_h
  5. #include "Heap.h"
  6. #endif
  7. #ifndef HeapLink_h
  8. #include "HeapLink.h"
  9. #endif
  10. #ifndef Swap_h
  11. #include "Swap.h"
  12. #endif
  13.  
  14. template< class Element >
  15. Heap< Element >::Heap( Comparator compare )
  16.   : nodeCount( 0 ),
  17.      top( 0 ),
  18.      below( compare )
  19.   {
  20.     Assert( compare != 0 );
  21.   }
  22.  
  23. template< class Element >
  24. Heap< Element >::~Heap()
  25.   {
  26.     Assert( nodeCount == 0 );
  27.     Assert( top == 0 );
  28.   }
  29.  
  30. template< class Element >
  31. HeapLink<Element>& Heap< Element >::Pop()
  32.   {
  33.     HeapLink<Element>& result = Top();
  34.     Remove( result );
  35.     return result;
  36.   }
  37.  
  38. template< class Element >
  39. void Heap< Element >::Add( LinkType& toAdd )
  40.   {
  41.     Assert( toAdd.heap == 0 );
  42.     toAdd.heap = this;
  43.     
  44.     Assert( toAdd.children[0] == 0 );
  45.     Assert( toAdd.children[1] == 0 );
  46.     
  47.     toAdd.path = ++nodeCount;
  48.     
  49.     LinkType **subHeap = ⊤
  50.     LinkType *carrying = &toAdd;
  51.     SinkNode( subHeap, carrying );
  52.  
  53.     Assert( *subHeap == 0 );
  54.     Assert( carrying->path == nodeCount );
  55.     Assert( carrying->children[0] == 0 );
  56.     Assert( carrying->children[1] == 0 );
  57.     
  58.     *subHeap = carrying;
  59.   }
  60.  
  61. template< class Element >
  62. void Heap< Element >::Remove( LinkType& toRemove )
  63.   {
  64.     Assert( toRemove.heap == this );
  65.     Assert( nodeCount > 0 );
  66.     
  67.     LinkType *spare( &RemoveLast() );
  68.     
  69.     if ( spare != &toRemove )
  70.       {
  71.         LinkType **subHeap = ⊤
  72.         spare->path = toRemove.path;
  73.         SinkNode( subHeap, spare );
  74.     
  75.         Assert( *subHeap == &toRemove );
  76.         Assert( spare->path == toRemove.path );
  77.     
  78.         *subHeap = spare;
  79.         toRemove.SwapWith( *spare );
  80.         Percolate( subHeap );
  81.       }
  82.     
  83.     toRemove.heap = 0;
  84.     Assert( toRemove.children[0] == 0 );
  85.     Assert( toRemove.children[1] == 0 );
  86.   }
  87.  
  88.  
  89. template< class Element >
  90. HeapLink<Element>** Heap< Element >::SubHeap( uint32 path )
  91.   {
  92.     Assert( path <= nodeCount );
  93.     Assert( path >= 1 );
  94.     
  95.     LinkType **subHeap = ⊤
  96.     uint32 remainingPath = path;
  97.     
  98.     while ( remainingPath > 1 )
  99.       {
  100.         Assert( *subHeap != 0 );
  101.         subHeap = &(*subHeap)->children[ remainingPath % 2 ];
  102.         remainingPath /= 2;
  103.       }
  104.     
  105.     Assert( *subHeap != 0 );
  106.     Assert( (*subHeap)->path == path );
  107.     return subHeap;
  108.   }
  109.  
  110. template< class Element >
  111. HeapLink<Element>& Heap< Element >::RemoveLast()
  112.   {
  113.     Assert( nodeCount > 0 );
  114.     LinkType **subHeap = SubHeap( nodeCount );
  115.     LinkType& removed = **subHeap;
  116.     *subHeap = 0;
  117.  
  118.     Assert( removed.children[0] == 0 );
  119.     Assert( removed.children[1] == 0 );
  120.     Assert( removed.heap == this );
  121.     Assert( removed.path == nodeCount );
  122.     removed.path = 0;
  123.     nodeCount--;
  124.     
  125.     return removed;
  126.   }
  127.  
  128. template< class Element >
  129. void Heap< Element >::SinkNode( LinkType**& subHeap,
  130.                                           LinkType*& carrying )
  131.   {
  132.     Assert( subHeap != 0 );
  133.     Assert( carrying != 0 );
  134.     
  135.     uint32 path = carrying->path;
  136.     
  137.     while( path > 1 )
  138.       {
  139.         Assert( *subHeap != 0 );
  140.         
  141.         if ( **subHeap > *carrying )
  142.           {
  143.             (*subHeap)->SwapWith( *carrying );
  144.             Swap( *subHeap, carrying );
  145.           }
  146.         
  147.         Assert( path > 1 );
  148.         subHeap = &(*subHeap)->children[ path % 2 ];
  149.         path /= 2;
  150.       }
  151.  
  152.     Assert( path == 1 );
  153.   }
  154.  
  155. template< class Element >
  156. void Heap< Element >::Percolate( LinkType** subHeap )
  157.   {
  158.     LinkType& dropping( **subHeap );
  159.     
  160.     while( true )
  161.       {
  162.         Assert( *subHeap == &dropping );
  163.         
  164.         LinkType *left = dropping.children[0];
  165.         LinkType *right = dropping.children[1];
  166.         
  167.         if ( left == 0 )
  168.           {
  169.             Assert( right == 0 );
  170.             break;
  171.           }
  172.         
  173.         if ( dropping > *left && ( right == 0 || *left <= *right ) )
  174.           {
  175.             dropping.SwapWith( *left );
  176.             Swap( *subHeap, left->children[0] );
  177.             
  178.             Assert( left->children[0] == &dropping );
  179.             Assert( *subHeap == left );
  180.             
  181.             subHeap = &left->children[0];
  182.             continue;
  183.           }
  184.         
  185.         if ( right == 0 )
  186.             break;
  187.         
  188.         if ( dropping > *right )
  189.           {
  190.             dropping.SwapWith( *right );
  191.             Swap( *subHeap, right->children[1] );
  192.             
  193.             Assert( right->children[1] == &dropping );
  194.             Assert( *subHeap == right );
  195.  
  196.             subHeap = &right->children[1];
  197.             continue;
  198.           }
  199.         
  200.         break;
  201.       }
  202.   }
  203.  
  204. template< class Element >
  205. void Heap< Element >::Validate( LinkType& node, uint32 level ) const
  206.   {
  207.     Assert( node.path > 0 );
  208.     Assert( node.path <= nodeCount );
  209.     Assert( node.heap == this );
  210.     Assert( !node.Null() );
  211.     
  212.     uint32 topBit = 1L << level;
  213.  
  214.     Assert( (node.path & topBit) != 0 );
  215.     Assert( node.path <= ( 2*topBit - 1) );
  216.  
  217.     if ( level == 31 )
  218.       {
  219.         Assert( node.children[0] == 0 );
  220.         Assert( node.children[1] == 0 );
  221.         return;
  222.       }
  223.     
  224.     uint32 rightChild = node.path | (topBit << 1);
  225.     uint32 leftChild = rightChild & ~topBit;
  226.     
  227.     if ( node.children[0] == 0 )
  228.       {
  229.         Assert( leftChild > nodeCount );
  230.       }
  231.      else
  232.       {
  233.         Assert( leftChild <= nodeCount );
  234.         Assert( node.children[0]->path == leftChild );
  235.         Assert( node <= *node.children[0] );
  236.         Validate( *node.children[0], level+1 );
  237.       }
  238.     
  239.     if ( node.children[1] == 0 )
  240.       {
  241.         Assert( rightChild > nodeCount );
  242.       }
  243.      else
  244.       {
  245.         Assert( rightChild <= nodeCount );
  246.         Assert( node.children[1]->path == rightChild );
  247.         Assert( node <= *node.children[1] );
  248.         Validate( *node.children[1], level+1 );
  249.       }
  250.   }
  251.  
  252. template< class Element >
  253. void Heap< Element >::Validate() const
  254.   {
  255.     Assert( below != 0 );
  256.     
  257.     if ( nodeCount == 0 )
  258.       {
  259.         Assert( top == 0 );
  260.       }
  261.      else
  262.       {
  263.         Assert( top != 0 );
  264.         Assert( top->path == 1 );
  265.         Validate( *top, 0 );
  266.       }
  267.   }
  268.